home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 10 - 1994 / 10.04 Apr 94 / Accurate Timing / TStats / LongArrayStats.c next >
Encoding:
C/C++ Source or Header  |  1994-02-11  |  3.3 KB  |  229 lines  |  [TEXT/KAHL]

  1. /* LongArrayStats ------------------------------------------------
  2.  *
  3.  * Calculate various statistics for arrays of longs.
  4.  *
  5.  * Copyright (c) 1993 Bill Karsh.
  6.  * All rights reserved.
  7.  *
  8.  */
  9.  
  10.  
  11. #pragma options( honor_register, !assign_registers )
  12.  
  13.  
  14. #include    "LongArrayStats.h"
  15. #include    <math.h>
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22. /* LongArrayMinMax -----------------------------------------------
  23.  *
  24.  * Calculate min and max values.
  25.  *
  26.  */
  27.  
  28. void LongArrayMinMax(
  29.     register long    *dp,
  30.     register long    N,
  31.     long            *min,
  32.     long            *max )
  33. {
  34.     register long    mx = 0x80000000, mn = 0x7fffffff, d;
  35.     
  36.     if( !N ) {
  37.         *min = *max = 0;
  38.         return;
  39.     }
  40.     
  41.     do {
  42.         d = *dp++;
  43.         if( d < mn ) mn = d;
  44.         if( d > mx ) mx = d;
  45.     } while( --N );
  46.     
  47.     *min = mn;
  48.     *max = mx;
  49. }
  50.  
  51.  
  52. /* LongArrayMeanDev ----------------------------------------------
  53.  *
  54.  * Calculate array's mean and standard deviation.
  55.  *
  56.  */
  57.  
  58. void LongArrayMeanDev(
  59.     register long    *dp,
  60.     long            N,
  61.     double            *mean,
  62.     double            *sd )
  63. {
  64.     register long    n = N, d;
  65.     register double    sumX, sumX2;
  66.     
  67.     sumX = sumX2 = 0;
  68.  
  69.     if( n ) {
  70.     
  71.         do {
  72.             d = *dp++;
  73.             sumX    += d;
  74.             sumX2    += d * d;
  75.         } while( --n );
  76.         
  77.         n = N;
  78.         
  79.         sumX    = sumX / n;
  80.         sumX2    = sumX2 / n - sumX * sumX;
  81.         if( n > 1 ) sumX2 *= n / (n - 1);
  82.         sumX2 = sqrt( sumX2 );
  83.     }
  84.     
  85.     *mean = sumX;
  86.     *sd = sumX2;
  87. }
  88.  
  89.  
  90. /* LongArrayBin --------------------------------------------------
  91.  *
  92.  * Bin data array into a bins array.
  93.  *
  94.  * If input bins is nil, this routine allocates the bins array.
  95.  *
  96.  */
  97.  
  98. long *LongArrayBin(
  99.     register long    *data,
  100.     register long    N,
  101.     register long    min,
  102.     long            max,
  103.     long            *bins,
  104.     register long    nBins )
  105. {
  106.     register long    *b;
  107.     register long    n, span;
  108.     
  109.     if( !bins )
  110.         bins = (long*)NewPtr( sizeof(long)*(nBins + 1) );
  111.     
  112.     if( !(b = bins) ) goto exit;
  113.     
  114. // zero bins array
  115.     
  116.     n = nBins + 1;
  117.     
  118.     do {
  119.         *b++ = 0;
  120.     } while( --n );
  121.     
  122. // bin data
  123.     
  124.     b = bins;
  125.  
  126.     if( span = max - min ) {
  127.         
  128.         do {
  129.             b[((*data++ - min) * nBins) / span]++;
  130.         } while( --N );
  131.     
  132.         b[nBins - 1] += b[nBins];
  133.     }
  134.     else
  135.         b[0] = N;
  136.         
  137. exit:
  138.     return bins;
  139. }
  140.  
  141.  
  142. /* LongArrayGetMaxBin --------------------------------------------
  143.  *
  144.  * Using an array {in} of data, and its corresponding array
  145.  * {bins}, return in array {out}, only those data falling
  146.  * in maximum height bin.
  147.  *
  148.  * in and out can be the same array.
  149.  *
  150.  */
  151.  
  152. void LongArrayGetMaxBin(
  153.     long            *in,
  154.     register long    nIn,
  155.     register long    min,
  156.     long            max,
  157.     long            *bins,
  158.     register long    nBins,
  159.     long            *out,
  160.     long            *nOut )
  161. {
  162.     register long    *insert, *look;
  163.     register long    newN, maxCounts;
  164.     short            maxBinNum, iBin, pad;
  165.     
  166. // quick exits
  167.  
  168.     if( !nIn ) {
  169.         *nOut = 0;
  170.         return;
  171.     }
  172.     
  173.     if( max == min ) {
  174.         *nOut = nIn;
  175.         if( in != out ) {
  176.             do {
  177.                 *out++ = *in++;
  178.             } while( --nIn );
  179.         }
  180.         return;
  181.     }
  182.     
  183. // find max bin
  184.  
  185.     maxBinNum    = 0;
  186.     maxCounts    = -1;
  187.     look        = bins;
  188.     
  189.     for( iBin = 0; iBin < (short)nBins; iBin++, look++ ) {
  190.         if( *look > maxCounts ) {
  191.             maxCounts = *look;
  192.             maxBinNum = iBin;
  193.         }
  194.     }
  195.  
  196.     
  197. // replace data with data in max bin
  198.  
  199.     newN    = 0;
  200.     look    = in;
  201.     insert    = out;
  202.     max    -= min;
  203.     
  204.     if( maxBinNum == nBins - 1 ) {    // edge condition
  205.  
  206.         do {
  207.             if( ((*look - min)*nBins)/max >= maxBinNum ) {
  208.                 *insert++ = *look;
  209.                 newN++;
  210.             }
  211.             look++;
  212.         } while( --nIn && newN < maxCounts );
  213.     }
  214.     else {
  215.  
  216.         do {
  217.             if( ((*look - min)*nBins)/max == maxBinNum ) {
  218.                 *insert++ = *look;
  219.                 newN++;
  220.             }
  221.             look++;
  222.         } while( --nIn && newN < maxCounts );
  223.     }
  224.     
  225.     *nOut = newN;
  226. }
  227.  
  228.  
  229.